package me.magicall.db.dao2;

import java.util.Collection;
import java.util.List;

import me.magicall.db.util.ReturnKeyAndAffect;

/**
 * 与具体表有关的dao,自带表名
 * 
 * @author MaGiCalL
 * @param <T>
 */
public interface Dao2<T> extends CommonDao<T> {

	/**
	 * 获取所有数据。
	 * 相当于 SELECT * FROM ...
	 * 
	 * @return
	 */
	List<T> all();

	/**
	 * 根据id获取一个对象的简便方法。
	 * 相当于 select ... where id=?
	 * 
	 * @param id
	 * @return
	 */
	T getById(final Object id);

	/**
	 * 根据id获取一个对象
	 * 相当于 select ... where id=?
	 * 
	 * @param id
	 * @param query
	 * @return
	 */
	T getById(final Object id, final Query<T> query);

	/**
	 * 根据一些条件获取一个对象。
	 * 注：符合条件的对象可能不唯一，可以根据queryConfig中指定的排序条件取出第一个符合条件的对象。
	 * 相当于 select ... where xx=? and yy=? ... order by ? limit 0,1
	 * 注:会忽略query中原有的PageInfo
	 * 
	 * @param query
	 * @return
	 */
	T getOne(final Query<T> query);

	/**
	 * 根据一些条件获取一些符合条件的对象
	 * 相当于 select ... where xx=? and yy=? ... order by ? limit ?,?
	 * 
	 * @param query
	 * @return
	 */
	List<T> list(final Query<T> query);

	int count(Query<T> query);

	int countAll();

	/**
	 * 根据某些条件删除一些对象
	 * 
	 * @param query
	 * @return
	 */
	int del(final Query<T> query);

	/**
	 * 根据id删除一些对象
	 * 使用delete from where id in(...)
	 * 
	 * @param id
	 * @return
	 */
	int delById(final Object... id);

	/**
	 * 根据id删除一些对象
	 * 使用delete from where id in(...)
	 * 
	 * @param id
	 * @return
	 */
	int delById(final Collection<? extends Object> id);

	/**
	 * 填充一个对象,需要预先设置好它的id
	 * 
	 * @param modelWithId
	 * @return
	 */
	T fill(T modelWithId);

	/**
	 * 填充一系列对象,需要预先设置好它们的id
	 * 
	 * @param modelWithId
	 * @return
	 */
	Collection<T> fill(T... modelWithId);

	/**
	 * 填充一系列对象,需要预先设置好它们的id
	 * 
	 * @param modelsWithId
	 * @return 返回的可能已经不是参数的collection
	 */
	Collection<T> fill(Collection<T> modelsWithId);

	/**
	 * 增加一个对象，并返回自增的主键
	 * 
	 * @param model
	 * @return
	 */
	ReturnKeyAndAffect addReturnKey(final T model) throws UnsupportedOperationException;

	/**
	 * 增加一批对象，并返回它们的自增主键
	 * 
	 * @param models
	 * @return
	 */
	ReturnKeyAndAffect addReturnKey(final T... models) throws UnsupportedOperationException;

	/**
	 * 增加一批对象，并返回它们的自增主键
	 * 
	 * @param models
	 * @return
	 */
	ReturnKeyAndAffect addReturnKey(final Collection<? extends T> models) throws UnsupportedOperationException;

	/**
	 * 尝试增加一批对象，如果某对象已存在，则忽略该对象
	 * 使用insert ignore into ...
	 * 
	 * @param models
	 * @return
	 */
	int addIfAbsent(final T... models) throws UnsupportedOperationException;

	/**
	 * 尝试增加一批对象，如果某对象已存在，则忽略该对象
	 * 使用insert ignore into ...
	 * 
	 * @param models
	 * @return
	 */
	int addIfAbsent(final Collection<? extends T> models) throws UnsupportedOperationException;

	/**
	 * 插入一个对象。如果对象已存在，会抛出异常
	 * 
	 * @param model
	 * @return
	 */
	boolean add(T model) throws UnsupportedOperationException;

	/**
	 * 插入一批对象。如果某对象已存在，会抛出异常。
	 * 
	 * @param models
	 * @return
	 */
	int[] add(T... models) throws UnsupportedOperationException;

	/**
	 * 插入一批对象。如果某对象已存在，会抛出异常。
	 * 
	 * @param models
	 * @return
	 */
	int[] add(Collection<? extends T> models) throws UnsupportedOperationException;

	/**
	 * 更新一个对象
	 * 
	 * @param model
	 * @return
	 */
	int update(T model) throws UnsupportedOperationException;

	/**
	 * 更新一批对象
	 * 使用update ... set ...
	 * 
	 * @param models
	 * @return
	 */
	int[] update(final T... models) throws UnsupportedOperationException;

	/**
	 * 更新一批对象
	 * 使用update ... set ...
	 * 
	 * @param models
	 * @return
	 */
	int[] update(final Collection<? extends T> models) throws UnsupportedOperationException;

	/**
	 * 插入一个对象,如果它已经存在,则更新它."存在"的依据是id
	 * 
	 * @param model
	 * @return
	 */
	boolean addOrUpdate(T model) throws UnsupportedOperationException;

	/**
	 * 尝试增加一批对象，如果某对象已存在，则更新其所有属性值
	 * 使用insert into ... on duplicate key update（似乎是mysql独有）
	 * 
	 * @param models
	 */
	int[] addOrUpdate(final T... models) throws UnsupportedOperationException;

	/**
	 * 尝试增加一批对象，如果某对象已存在，则更新其所有属性值
	 * 使用insert into ... on duplicate key update（似乎是mysql独有）
	 * 
	 * @param models
	 */
	int[] addOrUpdate(final Collection<? extends T> models) throws UnsupportedOperationException;

	/**
	 * 删除一个对象
	 * 如果参数中某个对象有id，则是delete ... where id=?，否则对model和数据库表记录进行全字段匹配删除。
	 * TODO:目前只使用了id字段
	 * 
	 * @param model
	 * @return
	 */
	int del(T model) throws UnsupportedOperationException;

	/**
	 * 删除一批对象。
	 * 如果参数中某个对象有id，则是delete ... where id=?，否则对model和数据库表记录进行全字段匹配删除。
	 * TODO:目前只使用了id字段
	 * 
	 * @param models
	 * @return
	 */
	int[] del(final Collection<? extends T> models) throws UnsupportedOperationException;

	/**
	 * 删除一批对象。
	 * 如果参数中某个对象有id，则是delete ... where id=?，否则对model和数据库表记录进行全字段匹配删除。
	 * TODO:目前只使用了id字段
	 * 
	 * @param models
	 * @return
	 */
	int[] del(final T... models) throws UnsupportedOperationException;
}
